enum TYPE {
  FADE = "fade",
  SLIDE = "slide",
}
interface ITabOptions {
  el: string;
  type: string;
}
class Base {
  private curIdx = 0;
  private tabItems: HTMLCollection;
  private pageItems: HTMLCollection | HTMLElement;
  private methodArr: any[] = [];
  private el: HTMLElement;

  constructor(el: HTMLElement, type: TYPE) {
    this.el = el;
    this.el.classList.add(type);
    this.tabItems = document.getElementsByClassName("tab-item");

    switch (type) {
      case TYPE.FADE:
        this.pageItems = document.getElementsByClassName("page-item");

        break;
      case TYPE.SLIDE:
        this.pageItems = document.querySelector(".inner") as HTMLElement;
        break;
      default:
        break;
    }
    this.init();
  }
  init() {
    this.bindEvent();
  }
  bindEvent() {
    this.el.addEventListener("click", this.navClick.bind(this), false);
  }
  navClick(e) {
    const ev = e || window.event,
      tar = ev.target;
    if (tar.className.trim() === "tab-item") {
      this.tabItems[this.curIdx].className = "tab-item";
      this.curIdx = [].indexOf.call(this.tabItems, tar);
      this.tabItems[this.curIdx].className = "tab-item active";
      this.notify();
    }
  }
  notify() {
    this.methodArr.forEach((v) => {
      v(this.pageItems, this.curIdx);
    });
  }
  getMethods(method) {
    this.methodArr.push(method);
  }
}
class Fade extends Base {
  constructor(el: HTMLElement) {
    super(el, TYPE.FADE);
    this.getMethods(this.setMethods);
  }
  setMethods(pageItems: HTMLElement, curIdx: number) {
    [...pageItems].forEach((v) => {
      v.className = "page-item";
    });
    pageItems[curIdx].className = "page-item active";
  }
}

class Slide extends Base {
  constructor(el: HTMLElement) {
    super(el, TYPE.SLIDE);
    this.getMethods(this.setMethods);
  }
  setMethods(pageItems: HTMLElement, curIdx: number) {
    pageItems.style.transform = `translate3d(${-curIdx * 500}px ,0,0)`;
  }
}

class Tab {
  private el: HTMLElement;
  private type: string;
  constructor(options: ITabOptions) {
    this.el = document.querySelector(options.el);
    this.type = options.type;
  }
  create() {
    switch (this.type) {
      case TYPE.FADE:
        return new Fade(this.el);
      case TYPE.SLIDE:
        return new Slide(this.el);
      default:
        break;
    }
  }
}
new Tab({
  el: ".tab",
  type: "slide",
}).create();
